<?php

declare(strict_types=1);
/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://hyperf.wiki
 * @contact  group@hyperf.io
 * @license  https://github.com/hyperf/hyperf/blob/master/LICENSE
 */

namespace App\Exception\Handler;

use App\Kernel\StdoutLogInterface;
use Hyperf\Config\Annotation\Value;
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\ExceptionHandler\ExceptionHandler;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Psr\Http\Message\ResponseInterface;
use Throwable;

class AppExceptionHandler extends ExceptionHandler
{
    /**
     * @var bool
     */
    #[Value("app_debug")]
    private $app_debug;

    public function __construct(protected StdoutLoggerInterface $logger, public StdoutLogInterface $stdoutLog)
    {
    }

    public function handle(Throwable $throwable, ResponseInterface $response)
    {
        $error = sprintf('%s[%s] in %s', $throwable->getMessage(), $throwable->getLine(), $throwable->getFile());
        $error_string = $throwable->getTraceAsString();

        $this->logger->error($error);
        $this->logger->error($error_string);

        // 自定义日志通道
        if ($this->app_debug) {
            $this->stdoutLog->log->error($error);
            $this->stdoutLog->log->error($error_string);
        }

        // 根据debug输出异常
        $body = $this->app_debug ? "{$error}\n{$error_string}" : 'Internal Server Error.';
        return $response->withHeader('Server', 'Hyperf')->withStatus(500)->withBody(new SwooleStream($body));
    }

    public function isValid(Throwable $throwable): bool
    {
        return true;
    }
}
